<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html><head><title>Programming in Lua : 13.4.5</title>
<link rel="stylesheet" type="text/css" href="pil.css">
</head>
<body>
<p class="warning">
<A HREF="contents.html"><IMG TITLE="Programming in Lua (first edition)" SRC="capa.jpg" ALT="" ALIGN="left"></A>This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.<BR>The third edition targets Lua 5.2 and is available at <A HREF="http://www.amazon.com/exec/obidos/ASIN/859037985X/theprogrammil3-20">Amazon</A> and other bookstores.<BR>By buying the book, you also help to <A HREF="../donations.html">support the Lua project</A>.
</p>
<table width="100%" class="nav">
<tr>
<td width="10%" align="left"><a href="13.4.4.html"><img border="0" src="left.png" alt="Previous"></a></td>
<td width="80%" align="center"><a href="contents.html"><font face="Helvetica,Arial,sanserif">
<font color="gray">Programming in </font><font color="blue"> Lua</font>
</font></a></td>
<td width="10%" align="right"><a href="14.html"><img border="0" src="right.png" alt="Next"></a></td>
</tr>
<tr>
<td width="10%" align="left"></td>
<td width="80%" align="center"><a href="contents.html#P2">Part II. Tables and Objects</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="contents.html#13">Chapter 13. Metatables and Metamethods</a></td>
<td width="10%" align="right"></td></tr>
</table>
<hr/>
<p><h3>13.4.5 &ndash; Read-Only Tables</h3>

<p>It is easy to adapt the concept of
proxies to implement read-only tables.
All we have to do is to raise an error whenever
we track any attempt to update the table.
For the <code>__index</code> metamethod,
we can use a table---the original table itself---instead of a function,
as we do not need to track queries;
it is simpler and quite more efficient to redirect all queries
to the original table.
This use, however,
demands a new metatable for each read-only proxy,
with <code>__index</code> pointing to the original table:
<pre>
    function readOnly (t)
      local proxy = {}
      local mt = {       -- create metatable
        __index = t,
        __newindex = function (t,k,v)
          error("attempt to update a read-only table", 2)
        end
      }
      setmetatable(proxy, mt)
      return proxy
    end
</pre>
(Remember that the second argument to <code>error</code>, 2,
directs the error message to where the update was attempted.)
As an example of use,
we can create a read-only table for weekdays:
<pre>
    days = readOnly{"Sunday", "Monday", "Tuesday", "Wednesday",
             "Thursday", "Friday", "Saturday"}
    
    print(days[1])     --> Sunday
    days[2] = "Noday"
    stdin:1: attempt to update a read-only table
</pre>

<p>
<hr/>
<table width="100%" class="nav">
<tr valign="top">
<td width="90%" align="left">
<small>
  Copyright &copy; 2003&ndash;2004 Roberto Ierusalimschy.  All rights reserved.
</small>
</td>
<td width="10%" align="right"><a href="14.html"><img border="0" src="right.png" alt="Next"></a></td>
</tr>
</table>


</body></html>

